#ifndef __DT_ADJACENT_HEADER__
#define __DT_ADJACENT_HEADER__



/* Data structures for representing triangle unit adjacencies are defined in 
   this header file, mesh adjacency informations would be used in the 
   correspondence algorithm to maintain the smoothness of deformed model. */


#include "dt_type.h"


/*
  "Adjacency smoothness" is a critical constraint in correspondencey matching 
  deformation, it forces the deformed mesh not being way too different from the
  source mesh by minimizing the difference of transformation matrices of each
  triangle and their adjacent triangles, this also maintains the smoothness of 
  the deformed mesh.


  ADJACENT (.adj) FILE FORMAT:
  --------------------------------------
  number of triangles
  0 [adjacent1, adjacent2, adjacent3]
  1 [adjacent1, adjacent2, adjacent3]
  2 [adjacent1, adjacent2, adjacent3]
  ...
  number of adjacencies
  --------------------------------------

  Be advised: any adjacency value of "-1" indicates an absent of adjacent
  triangle unit, it is just a placeholder for triangles with less than 3 
  adjacent triangle units.

*/
typedef struct __dt_AdjacentTriangleEntry_struct
{
    dt_index_type i_adjtriangle[3];   /* Indices of adjacent triangular units.
                                         Be advised: each triangle has at most
                                         three adjacent pieces in a well-formed
                                         mesh model. */
} __dt_AdjacentTriangleEntry;

typedef struct __dt_AdjacentTriangleList_struct
{
    /* List of adjacency entries
       adjacency[i]: 3 (or less) indexes of triangles adjacent to triangle i */
    __dt_AdjacentTriangleEntry *adjacency;

    dt_size_type   list_length;   /* number of entries, should be equal to the 
                                     number of triangles in the model */

    dt_size_type   n_adjacency;   /* number of adjacency pairs, 9 * n_adjacency
                                     should be the row number of the smoothness 
                                     equation */
} __dt_AdjacentTriangleList;



/* Allocate for adjacency_list with the size information specified in
   adjacency_list->list_length */
void __dt_CreateAdjacencyList(__dt_AdjacentTriangleList *adjacency_list);


/* Load pre-calculated triangle mesh adjacencies stored in a textfile to an 
   __dt_AdjacentTriangleList object. 

   This function returns total number of adjacencies, as well as the number of
   equations needed to illustrate transformation smoothness; if this function
   failed, an -1 is returned instead. 

   Failure is often caused by fopen(), check system variable errno to
   investigate why it failed.

   Be advised: this function in not designed to handle ill-formed files, no
   error-checking is implemented, provide well-formed .adj files generated by 
   the adjacency tool provided by this package, please.
*/
int __dt_LoadAdjacencies(
    const char *filename, __dt_AdjacentTriangleList *adj_list);



/* Find adjacent triangles for each triangle unit in the specified model.

   This routine is implemented in corres_resolve/adjacent_resolve.c, it employs
   a dictionary structure which is quite similar with hash table to accelerate
   the adjacency resolving procedure.
 */
void __dt_ResolveMeshAdjacencies(
    const dtMeshModel *model, __dt_AdjacentTriangleList *adjlist);

/* Find adjacent triangles for each triangle unit in the specified model.
   This implementation is brute-force and quite slow in practice, please 
   use the python version "adjtool/adjtool.py" or __dt_ResolveMeshAdjacencies
   instead. 

   This function returns total number of adjacent triangles of all triangular
   units in the model. */
dt_size_type __dt_ResolveMeshAdjacencies_BruteForce(
    const dtMeshModel *model, __dt_AdjacentTriangleList *adj_list);


/* Free the resources allocated for the adjacency list object */
void __dt_ReleaseAdjacencies(__dt_AdjacentTriangleList *adj_list);



typedef struct __dt_AdjacentTriangles_struct
{
    dt_size_type   n_adjtriangle;     /* number of adjacent triangles */
    dt_index_type  i_adjtriangle[3];  /* an array containing the indexes of 
                                         adjacent triangles */
} __dt_AdjacentTriangles;

/* This is an easy way to get the indexes of all triangles adjacent to a 
   queried triangle unit */
__dt_AdjacentTriangles __dt_GetAdjacentTriangles(
    const __dt_AdjacentTriangleList *adjlist, dt_index_type i_triangle);



/* Print all adjacencies to stdout, this function is only intent for debugging
   or testing purposes. */
void __dt_ShowAdjacencies(const __dt_AdjacentTriangleList *adj_list);




#endif /* __DT_ADJACENT_HEADER__ */
